package engine

import (
	"errors"
	"fmt"
)

type TokenType int8

const (
	LogicExpr TokenType = iota
	CaseExpr
	Operator
)

type  Token struct {
	Val string
	Type TokenType
	Offset int

}

type Parser struct {
	source string
	char byte
	offset int
	err error
}

func Parse(str string) ([]*Token, error){
	p := &Parser{
		source: str,
		err: nil,
		char: str[0],
	}
	tokens := p.parse()
	if p.err != nil{
		return nil, p.err
	}
	return tokens, p.err
}

func (p *Parser)parse() []*Token {
	tokens := make([]*Token, 0)
	for {
		token := p.nextToken()
		if token == nil{
			break
		}
		tokens = append(tokens, token)
	}
	return tokens
}
func (p *Parser)nextToken() *Token {
	if p.offset >= len(p.source) || p.err != nil{
		return nil
	}
	start := p.offset
	var token *Token
	if p.isOperator(p.char){
		token = &Token{
			Val: string(p.char),
			Type: Operator,
		}
		token.Offset = start
		_ = p.nextChar()

	}else if p.isLogicExpr(p.char){
		for p.isLogicExpr(p.char) && p.nextChar() == nil{}
		token = &Token{
			Val:p.source[start:p.offset],
		}
	}else if p.char == '!'{
		return nil
	}else {
		p.err = errors.New(fmt.Sprintf("无法识别的字符：[%v],pos[%v]", string(p.char), start))
	}
	return token
}

func (p *Parser)nextChar() error{
	p.offset++
	if p.offset < len(p.source){
		p.char = p.source[p.offset]
		return nil
	}
	return errors.New("EOF")
}

func (p *Parser)isOperator(ch byte)bool{
	return ch == ',' || ch == '+' || ch == '('|| ch == ')'
}
func (p *Parser)isLogicExpr(ch byte)bool{
	return '0'<= ch && ch <= '9' || 'A' <= ch && ch <= 'z' || ch == '.' || ch == '-' || ch == '#'|| ch == '='
}